What is openapi-typescript?
The openapi-typescript npm package is a tool that generates TypeScript types from OpenAPI specifications. This helps developers ensure type safety and better integration between their API definitions and TypeScript code.
What are openapi-typescript's main functionalities?
Generate TypeScript Types
This feature allows you to generate TypeScript types from an OpenAPI specification URL. The generated types are then saved to a file named 'types.ts'.
const openapiTS = require('openapi-typescript');
const fs = require('fs');
async function generateTypes() {
const types = await openapiTS('https://api.example.com/openapi.json');
fs.writeFileSync('types.ts', types);
}
generateTypes();
Generate Types from Local File
This feature allows you to generate TypeScript types from a local OpenAPI specification file. The generated types are saved to a file named 'types.ts'.
const openapiTS = require('openapi-typescript');
const fs = require('fs');
const path = require('path');
async function generateTypes() {
const types = await openapiTS(path.join(__dirname, 'openapi.json'));
fs.writeFileSync('types.ts', types);
}
generateTypes();
Custom Type Generation Options
This feature allows you to customize the type generation process by providing options such as a transform function. The transform function can be used to modify the schema before generating the types.
const openapiTS = require('openapi-typescript');
const fs = require('fs');
async function generateTypes() {
const types = await openapiTS('https://api.example.com/openapi.json', {
transform: (schema) => {
// Custom transformation logic
return schema;
}
});
fs.writeFileSync('types.ts', types);
}
generateTypes();
Other packages similar to openapi-typescript
swagger-typescript-api
The swagger-typescript-api package generates TypeScript API client code from Swagger/OpenAPI definitions. It provides more advanced features like generating API client methods and supports both Swagger 2.0 and OpenAPI 3.0 specifications.
typescript-fetch
The typescript-fetch package is a generator for TypeScript clients using the Fetch API. It generates TypeScript code from OpenAPI specifications and is particularly useful for creating client-side code that interacts with RESTful APIs.
📘️ openapi-typescript
🚀 Convert OpenAPI 3.0 and 2.0 (Swagger) schemas to TypeScript interfaces using Node.js.
Features
- ✅ OpenAPI 3.0
- ✅ Swagger 2.0
- ✅ Supports YAML and JSON schema formats
- ✅ Supports loading via remote URL (simple authentication supported with the
--auth
flag) - ✅ Supports remote references:
$ref: "external.yaml#components/schemas/User"
- ✅ Formats using Prettier
- ✅ TypeScript 4.0 features
Examples
Usage
🖥️ CLI
🗄️ Reading specs from file system
npx openapi-typescript schema.yaml --output schema.ts
npx openapi-typescript "specs/**/*.yaml" --output schemas/
Note: if generating a single schema, --output
must be a file (preferably *.ts
). If using globs, --output
must be a directory.
Thanks to @sharmarajdaksh for the glob feature!
☁️ Reading specs from remote resource
npx openapi-typescript https://petstore.swagger.io/v2/swagger.json --output petstore.ts
Note: globbing doesn’t work for remote schemas because there is no reliable way to determine a list of files to select from a remote file system.
Thanks to @psmyrdek for the remote spec feature!
Using in TypeScript
Import any top-level item from the generated spec to use it. It works best if you also alias types to save on typing:
import { components } from "./generated-schema.ts";
type APIResponse = components["schemas"]["APIResponse"];
Because OpenAPI schemas may have invalid TypeScript characters as names, the square brackets are a safe way to access every property.
Also note that there’s a special operations
interface that you can import OperationObjects
by their operationId:
import { operations } from "./generated-schema.ts";
type getUsersById = operations["getUsersById"];
Even though operations
isn’t present in your original schema, it’s a simple convenience and won’t disrupt any of your other types.
Thanks to @gr2m for the operations feature!
openapi-typescript-fetch
The generated spec can also be used with openapi-typescript-fetch which implements a typed fetch client for openapi-typescript.
import { paths } from "./petstore";
import { Fetcher } from "openapi-typescript-fetch";
const fetcher = Fetcher.for<paths>()
fetcher.configure({
baseUrl: "https://petstore.swagger.io/v2",
init: {
headers: {
...
},
},
use: [...]
})
const findPetsByStatus = fetcher.path("/pet/findByStatus").method("get").create()
const addPet = fetcher.path("/pet").method("post").create()
try {
const { status, data: pets } = await findPetsByStatus({
status: ["available", "pending"],
})
await addPet({ ... })
} catch(e) {
if (e instanceof addPet.Error) {
const error = e.getActualType()
if (error.status === 400) {
error.data.validationErrors
} else if (error.status === 500) {
error.data.errorMessage
} else {
...
}
}
}
Outputting to stdout
Simply omit the --output
flag to return to stdout:
npx openapi-typescript schema.yaml
CLI Options
Option | Alias | Default | Description |
---|
--output [location] | -o | (stdout) | Where should the output file be saved? |
--auth [token] | | | (optional) Provide an auth token to be passed along in the request (only if accessing a private schema) |
--header | -x | | (optional) Provide an array of or singular headers as an alternative to a JSON object. Each header must follow the key: value pattern |
--headersObject | -h | | (optional) Provide a JSON object as string of HTTP headers for remote schema request. This will take priority over --header |
--httpMethod | -m | GET | (optional) Provide the HTTP Verb/Method for fetching a schema from a remote URL |
--immutable-types | -it | false | (optional) Generates immutable types (readonly properties and readonly array) |
--additional-properties | -ap | false | (optional) Allow arbitrary properties for all schema objects without additionalProperties: false |
--default-non-nullable | | false | (optional) Treat schema objects with default values as non-nullable |
--prettier-config [location] | -c | | (optional) Path to your custom Prettier configuration for output |
--export-type | | false | (optional) Export type instead of interface |
--support-array-length | | false | (optional) Generate tuples using array minItems / maxItems |
--make-paths-enum | -pe | false | (optional) Generate an enum of endpoint paths |
--path-params-as-types | | false | (optional) Substitute path parameter names with their respective types |
--raw-schema | | false | Generate TS types from partial schema (e.g. having components.schema at the top level) |
--version | | | Force OpenAPI version with --version 3 or --version 2 (required for --raw-schema when version is unknown) |
🐢 Node
npm i --save-dev openapi-typescript
import fs from "fs";
import openapiTS from "openapi-typescript";
const schema = await fs.promises.readFile("spec.json", "utf8")
const output = await openapiTS(JSON.parse(schema));
const localPath = new URL("./spec.yaml", import.meta.url);
const output = await openapiTS(localPath);
const output = await openapiTS("https://myurl.com/v1/openapi.yaml");
The Node API may be useful if dealing with dynamically-created schemas, or you’re using within context of a larger application. Pass in either a JSON-friendly object to load a schema from memory, or a string to load a schema from a local file or remote URL (it will load the file quickly using built-in Node methods). Note that a YAML string isn’t supported in the Node.js API; either use the CLI or convert to JSON using js-yaml first.
⚠️ As of v4.0
, openapiTS()
is an async function.
Custom Formatter
If using the Node.js API, you can optionally pass a formatter to openapi-typescript. This is useful if you want to override the default types and substitute your own.
For example, say your schema has the following property:
properties:
updated_at:
type: string
format: date-time
By default, this will generate a type updated_at?: string;
. But we can override this by passing a formatter to the Node API, like so:
const types = openapiTS(mySchema, {
formatter(node: SchemaObject) {
if (node.format === "date-time") {
return "Date";
}
});
This will generate updated_at?: Date
instead. Note that you will still have to do the parsing of your data yourself. But this will save you from having to also update all your types.
Note: you don’t have to use .format
—this is just an example! You can use any property on a schema object to overwrite its generated type if desired.
🏅 Project Goals
- Support converting any OpenAPI 3.0 or 2.0 (Swagger) schema to TypeScript types, no matter how complicated
- The generated TypeScript types must match your schema as closely as possible (i.e. don’t convert names to
PascalCase
or follow any TypeScript-isms; faithfully reproduce your schema as closely as possible, capitalization
and all) - This library is a TypeScript generator, not a schema validator.
🤝 Contributing
PRs are welcome! Please see our CONTRIBUTING.md guide. Opening an issue beforehand to discuss is
encouraged but not required.
Contributors ✨
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification.
Contributions of any kind welcome!